package cz.apnetis.gwt.client;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/** Object of this class contains definition of header of table
 * @author Lukas "benzin" Benda <a href="mailto:bendal@apnet.cz">bendal@apnet.cz</a>
 * @since Oct 2, 2010
 */
public class TableColumnHeaders extends Composite implements HasWidgets {

  /** List of widgets which define column header, each widget define one header column */
  private final List<Widget> columnHeaders = new ArrayList<Widget>();
  /** Name of visible columns */
  private List<String> visibleColumns;

  public final List<String> getVisibleColumns() {
    return this.visibleColumns;
  }

  public void setVisibleColumns(final List<String> visibleColumns) {
    this.visibleColumns = visibleColumns;
  }
  /** Image which is used for editing of shown column */
  private Image configIco = null;
  /** Table which own this table */
  private ResultTable<?, ?> resultTable; public void setResultTable(final ResultTable<?, ?> resultTable) { this.resultTable = resultTable; } public ResultTable<?, ?> getResultTable() { return this.resultTable; }

  public TableColumnHeaders() {
    super();
  }

  public final void initializeSettingImage() {
    if (this.configIco == null) {
      this.configIco = new Image(ActionIconImages.INSTANCE.icon_config());
      this.configIco.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          final PopupPanel panel = new PopupPanel(true);
          final VerticalPanel vp = new VerticalPanel();
          panel.add(vp);
          for (final String columnName : TableColumnHeaders.this.resultTable.getTableModel().getColumnNames()) {
            final String columnNameI18n = TableColumnHeaders.this.resultTable.getTableModel().getColumnNameI18n(columnName);

            final CheckBox checkBox = new CheckBox(columnNameI18n);
            checkBox.setValue(Boolean.valueOf(getVisibleColumns().contains(columnName)));
            checkBox.addClickHandler(new SelectColumnHandler(
                TableColumnHeaders.this.resultTable, columnName));
            vp.add(checkBox);
          }
          panel.setPopupPosition(TableColumnHeaders.this.configIco.getAbsoluteLeft(), TableColumnHeaders.this.configIco.getAbsoluteTop());
          panel.show();
        }
      });
    }
  }

  /** Method which append column header to grid */
  public final void appendHeader(final Grid table) {
    table.getRowFormatter().addStyleName(0, "th");
    int colShift = 0;
    if (table.getColumnCount() > size()) {
      table.setWidget(0, 0, this.configIco);
      colShift++;
    }

    final Iterator<Widget> itt = iterator();
    int col = colShift;
    for (final String columnName : this.resultTable.getTableModel().getColumnNames()) {
      final Widget w = itt.next();
      if (getVisibleColumns().contains(columnName)) {
        table.setWidget(0, col, w);
        col++;
      }
    }
  }

  /** Count of headers in table */
  public final int size() {
    return this.visibleColumns.size();
  }

  /** Comma separate list of visible columns */
  public final void setVisibleColumnsAsString(final String visibleColumns) {
    final String[] col = visibleColumns.split(",");
    final List<String> cols = new ArrayList<String>(col.length);
    for (final String c : col) { cols.add(c); }
    setVisibleColumns(cols);
  }

  @Override
  public void add(final Widget w) {
    this.columnHeaders.add(w);
  }
  @Override
  public void clear() {
    this.columnHeaders.clear();
  }
  @Override
  public Iterator<Widget> iterator() {
    return this.columnHeaders.iterator();
  }
  @Override
  public boolean remove(final Widget w) {
    return this.columnHeaders.remove(w);
  }

  public static class SelectColumnHandler implements ClickHandler {
    private final ResultTable<?, ?> table;
    private final String columnName;

    public SelectColumnHandler(final ResultTable<?, ?> table,
        final String columnName) {
      this.table = table;
      this.columnName = columnName;
    }

    @Override
    public void onClick(final ClickEvent event) {
      final List<String> list = new ArrayList<String>();
      for (final String colNam : this.table.getTableModel().getColumnNames()) {
        if (this.table.getColumnHeaders().getVisibleColumns().contains(colNam)) {
          if (!colNam.equals(this.columnName)) {
            list.add(colNam);
          }
        } else if (colNam.equals(this.columnName)) {
          list.add(colNam);
        }
      }
      this.table.getColumnHeaders().setVisibleColumns(list);
      this.table.repaint();
    }
  }
}
